<!-- fr.upmc.components.exemples.basic_cs -->
<html>
<body>
<p><b>Basic client/server example</b></p>

<p>
In this example, a basic client/server is constructed.  Upon a call, the server
will provide a string that is an URI.
</p>

<p>Here are the steps from the design to execution:</p>
<ol>
<li>The first step is to define the <b>interfaces</b> of the components.  In
  this example, the offered interface is <code>URIProviderI</code>, which
  defines a method <code>proideURI</code>.  Notice that this method throws an
  exception, as it is required from the RMI protocol that all methods
  that can be called through RMI throws at least the
  <code>java.rmi.RemoteException</code>.  The required interface is
  <code>URIConsumerI</code>.  As in component-based programming, client and
  server components need not be designed by the same persons, and may be
  connected after their design and implementation, the required interface does
  not necessarily use the same signatures for the service.  A method in a
  required interface does not have to throw an exception, but here as the
  service method does, we add the exception throwing declaration to be able
  to propagate the exception if necessary.
</li>
<li>The second step is beginning to define the components, starting with the
  server component in order to know what will be the service methods.  The
  component is a subclass of <code>AbstractComponent</code> called
  <code>URIProvider</code>, to which we add a method
  <code>provideURIService</code>.
</li>
<li>The third step is to define the inbound port to expose the offered interface
  of the component.  The port is created as a subclass of
  <code>AbstractInboundPort</code> named <code>URIProviderInboundPort</code>.
  See the documentation of this class for details about the port design and
  implementation.
  </li>
<li>The fourth step is to compile the RMI stubs for the port so that it can be
  exported a a RMI remote object.  The file
  <code>compiling-basic_cs-rmi-stubs.xml</code> gives an ant script to do so
  and can serve as example of a good way to do that in your programming
  projects.
</li>
<li>The fifth step is now to come back to the server component and complete
  its creation so that it creates and publish its inbound port.  To do so,
  a constructor must be provided to <codeURIProvider</code>, taling as basis
  the constructors of the class <code>AbstractComponent</code>.  Here, we want
  an active component with one thread, so we use the constructor
  <code>AbstractComponent(boolean)</code> as a basis.  Beware that component
  interfaces must be added to the appropriate sets, ports must be put into
  the set of ports of the component and published appropriately when needed.
</li>
<li>The sixth step is to implement the outbound port that will be used by the
  client component.  The port is a subclass of <code>AbstractOutboundPort</code>
  called <code>URIGetterOutboundPort</code>.  As other outbound port, it
  implements the required interface to make it possible for the owner component
  to call it, and upon such a call, it transfers it to the connector, that will
  itself call the inbound port of the server component.
</li>
<li>The seventh step is to define and implement the client component.  In this
  short example, the client component will play the active role, calling the
  service ten times and printing the returned URI.  Tasks are created as
  implementations of the interface <code>ComponentTask</code> defined in the
  interface <code>ComponentI</code>.  It only requires to define a run method,
  which in this case calls an internal method <code>getURIandPrint</code>
  that implements the component's behaviour.
</li>
<li>The eight step is to implement the connector, a simple client server
  connector subclass of <code>AbstractConnector</code> called
  <code>URIServiceConnector</code>.  This connector implements the required
  interface by simply calling the inbound port with the corresponding offered
  method.
</li>
<li>The ninth step is to define the assembly, but then you must choose
  between a local execution within one JVM, or a distributed one over several
  JVM.  The steps differ, so they are explained separately for the two cases.
</li>
<li>The tenth step is execution, but again it differs whether the execution is
  using one or several JVM, so the steps are explained separately for the two
  cases.
</li>
</ol>

<p><b>The single JVM case</b></p>

<p>
In the single JVM case, an assembly is created by a component virtual machine
itself as a subclass of <code>AbstractCVM</code>, called <code>CVM</code>.
This CVM deploys two components: a provider and a consumer.  The two are
connected by their inbound and outbound ports respectively, through the connector.
To connect two ports, it is necessary that to know the URI of the two ports
to be connected.  For simplicity, <code>CVM</code> defines them as static
constants.
</p>
<p>
Next, the method <code>deploy</code> must be implemented to create the
components, publish their ports and connect them.  Notice here that the
provider component is created by passing the constant false to the constructor
of <code>URIProvider</code>, hence its inbound port will be published only
locally, as single JVM deployment do not use a global and RMI registry.
A connector is instantiated from <code>URIServiceConnector</code> and used
to connect the two components by calling the method <code>connectWith</code> on
<code>ConnectionBuilder.SINGLETON</code>.
</p>
<p>
The main method of the CVM creates an instance of <code>CVM</code>, calls its
method <code>deploy</code>, then its method <code>start</code>, waits until the
consumer finished its processing, and then call its method <code>shutdown</code>
and <code>System.exit(0)</code>.  The class <code>CVM</code> can the be run as
any Java application, as it appears in this first screen shot before starting
the execution where the source are placed in the subdirectory <code>jars</code>:
</p>

<img SRC="../../../../../../images/before-execution.jpg"/>

<p>
During the execution, the consumer prints a new URI each 2 seconds:
</p>

<img SRC="../../../../../../images/during-execution.jpg"/>

<p>
At the end of the execution, the ten URI have been printed and the control
returns to the shell.
</p>

<img SRC="../../../../../../images/after-execution.jpg"/>

<p><b>The multiple JVM case</b></p>

<p>
In the multiple JVM case, a distributed assembly is created by a distributed
CVM itself defined as a subclass of <code>AbstractDistributedCVM</code>, called
<code>DistributedCVM</code>.  But before going into the code of this class, the
programmer must decide a deployment and its configuration.  A distributed CVM
will be run on several JVM, and eventually on several hosts.  Connecting
components running on different JVM uses RMI, which requires the publication of
remote objects (here component ports) on a RMI registry, and in the openly
available implementations of Java, a RMI registry cannot be changed by code
running on a different host, so one need to have one RMI registry running per
host.  All of these requirements force every part of the distributed CVM to have
informations about the registry and the registry needs to know about the number
of JVM implied in an execution.  A configuration file in XML is used to provide
this information, and such configuration files obey a Relax NG schema provided
with the component model implementation.  In our client server example, it
looks like follows:
</p>
<pre>
&lt;deployment&gt;
  &lt;cyclicBarrier   hostname="localhost" port="55253"/&gt;
  &lt;globalRegistry  hostname="localhost" port="55252"/&gt;
  &lt;rmiRegistryPort no="55999"/&gt;
  &lt;jvms2hostnames&gt;
    &lt;jvm2hostname jvmuri="provider" rmiRegistryCreator="true"
                  hostname="localhost"/&gt;
    &lt;jvm2hostname jvmuri="consumer" rmiRegistryCreator="false"
                  hostname="localhost"/&gt;
  &lt;/jvms2hostnames&gt;
&lt;/deployment&gt;
</pre>
<p>
This distributed CVM deploys the two same components, a provider and a
consumer, in two distinct JVM called <code>provider</code> and
<code>consumer</code>.  The two JVM are run on the same host,
<code>localhost</code>.  As we need to have on RMI registry per host, one
and only one JVM per host must be declared as the RMI registry creator,
the other will use the same registry.  The first three lines provide
information about the central resources: the host running the assembly
cyclic barrier and the port on which it listens, the host that runs the
global registry and the port on which it listens, and the port used by the
different RMI registry.
</p>
<p>
The code of <code>DistributedCVM</code> uses the names of the JVM to know where
to statically create the components and where to perform the connections and
disconnections of the components.  The <code>deploy</code> method is now
decomposed into three methods, <code>initialise</code>,
<code>instantiateAndPublish</code> and <code>interconnect</code>, and
the different DCVM sites synchronise with each other at each step.
<code>initialise</code> can be used to do anything required before the
creation of components, and in the base class it creates and initialises
the references to the RMI registry.  <code>instantiateAndPublish</code>
creates each component on the right JVM and publishes their ports.
<code>interconnect</code> creates the connectors and performs the
connections but in only one JVM for each connection, the one of one
of the two connected components.  The method <code>main</code> creates
an instance of <code>DistributedCVM</code>, calls <code>deploy</code>
and <code>start</code> on it, wait 15 seconds for the consumer component
to completes its execution, and then call <code>shutdown</code> and exits.
</p>

<p>
Note also that the code need to have access to the schema of the configuration
file, <code>deployment.rnc</code>, put in a subdirectory <code>config</code>.
It also needs to have access to jars of the code: the basic component model,
the code of the component-based application, as well as the following XML tools:
</p>
<ul>
<li><code>isorelax.jar</code></li>
<li><code>saxon.jar</code></li>
<li><code>xml-apis.jar</code></li>
<li><code>xercesImpl.jar</code></li>
<li><code>jing.jar</code></li>
</ul>

<p>
To execute the application, two JVM must be started to execute the global
registry and the DCVM cyclic barrier, and two others to run the components.
Three shell scripts are provided to ease this, the script
<code>start-gregistry</code>:
</p>

<pre>
#!/bin/bash
java -cp &apos;jars/*&apos; -Djava.security.manager -Djava.security.policy=dcvm.policy fr.upmc.components.registry.GlobalRegistry config.xml
</pre>

<p>
the script <code>start-cyclicbarrier</code>:
</p>

<pre>
#!/bin/bash
java -cp 'jars/*' -Djava.security.manager -Djava.security.policy=dcvm.policy fr.upmc.components.cvm.utils.DCVMCyclicBarrier config.xml
</pre>

<p>
and the script <code>start-dcvm</code>:
</p>

<pre>
#!/bin/bash
if [ -z "$1" ]; then 
  echo usage: $0 jvmName
  exit
 fi
java -ea -cp 'jars/*' -Djava.security.manager -Djava.security.policy=dcvm.policy fr.upmc.components.examples.basic_cs.DistributedCVM $1 config.xml
</pre>
<p>
that requires adaptation for each application and which receives as command
line parameter the name of the JVM it executes in the DCVM deployment.
</p>

<p>
Notice the use of a security manager to give the application the necessary
rights to access the files and use sockets, etc.  The policy file used in this
application is:
</p>
<pre>
grant {
  permission java.util.PropertyPermission "javax.xml.validation.SchemaFactory:http://relaxng.org/ns/structure/1.0", "read,write";
  permission java.io.FilePermission "./config/deployment.rnc", "read";
  permission java.io.FilePermission "./config.xml", "read";
  permission java.io.FilePermission "user.dir/tmp/*.log", "write";
  permission java.util.PropertyPermission "user.dir", "read";
  permission java.net.SocketPermission "*:1999", "connect, resolve";
  permission java.net.SocketPermission "*:1024-", "connect, resolve";
  permission java.net.SocketPermission "*:1024-", "accept, resolve";
  permission java.lang.RuntimePermission "stopThread";
  permission java.lang.RuntimePermission "modifyThread";
  permission java.lang.RuntimePermission "modifyThreadGroup";
};
</pre>

<p>
The next screen shot shows four shell windows with the four command ready to
be executed:
</p>
<img SRC="../../../../../../images/before-distributed-execution.jpg"/>

<p>
Similarly to the single JVM case, during the execution, the progress of the
consumer can be seen in its window:
</p>
<img SRC="../../../../../../images/during-distributed-execution.jpg"/>

<p>
And at the end, the list of produced URI is completed, and all of the processes
have stopped and returned to the shell:
</p>
<img SRC="../../../../../../images/after-distributed-execution.jpg"/>

</body>
</html>